
#include <socket/datagram_socket.hpp>

#include <gtest/gtest.h>

namespace Tux { namespace Socket { namespace Test
{
    using namespace ::testing;

    class DatagramSocketTest : public ::testing::Test
    {
    protected:
        typedef DatagramSocket<LocalDomainTraits> LocalDatagramSocket;

        DatagramSocketTest()
            : mLocalSocketAddress(LocalDomainTraits::CreateSocketAddress("./gtesting"))
        {
            unlink("./gtesting");
        }

        LocalDomainTraits::SocketAddress mLocalSocketAddress;
    };

    TEST_F(DatagramSocketTest, ManualAttempt)
    {
        int fd = socket(PF_UNIX, SOCK_DGRAM, 0);
        EXPECT_NE(0, fd);
        struct sockaddr_un addr;
        memset(&addr, 0, sizeof(struct sockaddr_un));
        addr.sun_family = AF_UNIX;
        sprintf(addr.sun_path + 1, "./manual");
        EXPECT_EQ(0, bind(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un)));
        close(fd);
    }

    TEST_F(DatagramSocketTest, LocalDatagramSocket_TinyDatagram)
    {
        uint8_t out[] = { 0x3F };
        uint8_t in[256];
        LocalDomainTraits::SocketAddress source;
        LocalDatagramSocket receiver, sender;
        memset(&source, 0, sizeof(LocalDomainTraits::SocketAddress));
        receiver.Bind(mLocalSocketAddress);
        sender.Send(out, sizeof(out), mLocalSocketAddress);
        EXPECT_EQ(sizeof(out), receiver.Receive(in, sizeof(int), &source));
        EXPECT_EQ(0, memcmp(out, in, sizeof(out)));
        EXPECT_EQ(0, memcmp(&mLocalSocketAddress, &source, sizeof(source)));
    }
}}}

